package com.example.leave.application;

import com.example.leave.application.client.InfrastructureClient;
import com.example.leave.application.client.dto.OrganizationDto;
import com.example.leave.application.client.dto.PersonDto;
import com.example.leave.domain.approval.aggregate.ApprovalRule;
import com.example.leave.domain.approval.service.ApprovalDomainService;
import com.example.leave.domain.leave.aggregate.Leave;
import com.example.leave.domain.leave.aggregate.valueObject.Applicant;
import com.example.leave.domain.leave.aggregate.valueObject.Approver;
import com.example.leave.domain.leave.aggregate.valueObject.LeaveType;
import com.example.leave.infrastructure.mapper.ApproverMapper;
import org.springframework.stereotype.Service;

/**
 * TODO
 *
 * @author lxh
 * @date 2020/11/25 上午9:46
 **/
@Service
public class LeaveApplication {
    private final InfrastructureClient infrastructureClient;
    private final ApproverMapper approverMapper;
    private final ApprovalDomainService approvalDomainService;

    public LeaveApplication(
            InfrastructureClient infrastructureClient,
            ApproverMapper approverMapper,
            ApprovalDomainService approvalDomainService) {
        this.infrastructureClient = infrastructureClient;
        this.approverMapper = approverMapper;
        this.approvalDomainService = approvalDomainService;
    }

    /**
     * 查找下一审批人
     * @param leave  请假条
     * @return 下一审批人，null 表示当前审批人已是最终审批人
     */
    public Approver findNextApprover(Leave leave) {
        Applicant applicant = leave.getApplicant();
        LeaveType leaveType = leave.getLeaveType();
        int duration = leave.getDuration();
        Approver approver = leave.getApprover();

        OrganizationDto applicantOrg =
                infrastructureClient.findPersonById(applicant.getPersonId()).getOrganization();
        // 1. 若 approver 为空，说明是第一次提交
        if (approver == null) {
            // 若申请人本身就是部门领导，则向上审批
            PersonDto manager = infrastructureClient.findManager(applicantOrg.getOrgId());
            if (manager.getPersonId().equals(applicant.getPersonId())) {
                OrganizationDto parent = applicantOrg.getParent();
                // 若申请人本身已是最高领导，则只能返回自己了
                if (parent == null) {
                    return approverMapper.toApprover(manager);
                }
                return approverMapper.toApprover(infrastructureClient.findManager(parent.getOrgId()));
            }
            // 否则直接返回申请人所在部门的部门领导
            return approverMapper.toApprover(manager);
        }

        // 2. 获取当前请假条的最大审批级别；
        ApprovalRule approvalRule = approvalDomainService.getApprovalRule(leaveType, duration);
        if (approvalRule == null) {
            throw new IllegalArgumentException("没有匹配到审批规则");
        }
        int maxLevel = approvalRule.getMaxLevel();

        // 3. 若 approver 所在部门已经是最大审批级别所在的部门，说明已经是最终审批人，返回null即可；
        OrganizationDto approverOrg =
                infrastructureClient.findPersonById(approver.getPersonId()).getOrganization();
        OrganizationDto org = applicantOrg;
        for (int i = 0; i < maxLevel - 1; i++) {
            OrganizationDto currentOrg = org;
            org = org.getParent();
            if (org == null) {
                return approverMapper.toApprover(infrastructureClient.findManager(currentOrg.getOrgId()));
            }
        }
        if (approverOrg.getOrgId().equals(org.getOrgId())) {
            return approver;
        }

        // 4. 否则，返回 approver 所在部门的上级部门的部门领导
        return approverMapper.toApprover(
                infrastructureClient.findManager(approverOrg.getParent().getOrgId()));
    }
}
